
// 自定义绘制图案方法
export default class Custom {

  constructor(ctx){
    this.Ctx = ctx;
  }

  // 改变场景内图案颜色
  setColor(ele){
    if(ele.fillType === 'stroke'){
      this.Ctx.ctx.strokeStyle = ele.fillColor || "rgb(0,0,0)";
    }else{
      this.Ctx.ctx.fillStyle = ele.fillColor || "rgb(0,0,0)";
    }
  }

  // 改变场景内的文字大小
  textFont({font}){
    if(font){ // 不再对类型做判断，传入参数不对时会不生效
      this.Ctx.ctx.font = font
    } else {
      this.Ctx.ctx.font = '12px serif'
    }
  }

  // 自定义绘制图案
  // start: {x:'', y:''}
  // lineWay: 绘制线路坐标  [[x, y], [x1,y1]]
  // fillType: 类型  fill 实心   stroke 空心
  customDraw({start, lineWay, fillType = 'fill', fillColor, lineWidth}){
    if(!lineWay) return new Error('缺少路线坐标');
    this.Ctx.ctx.lineWidth = lineWidth || 1;
    this.setColor({fillColor, fillType})
    this.Ctx.ctx.beginPath();
    this.Ctx.ctx.moveTo(start.x, start.y);
    for(let i of lineWay){
      this.Ctx.ctx.lineTo(...i);
    }
    if(fillType === 'fill') {
      this.Ctx.ctx.fill();
    } else {
      this.Ctx.ctx.stroke();
    }

  }

  // 添加自定义文字
  customText({x, y, text, font, fillType = 'fill', fillColor}){
    if(!text) return;
    this.setColor({fillColor, fillType})
    this.textFont({font})
    if(fillType === 'fill'){
      this.Ctx.ctx.fillText(text, x, y);
    }else{
      this.Ctx.ctx.strokeText(text, x, y)
    }
  }

  // 获取文字位置
  // maxWidth: 最大宽度
  textPosition({ele, maxWidth = 1000}){
    let res = {
      x: 0,
      y:0,
      textArr: [],
      lineHeight: 0,
    };
    if(!ele.textInfo || !ele.textInfo.text) return res;
    let {actualBoundingBoxAscent, actualBoundingBoxDescent, actualBoundingBoxLeft, actualBoundingBoxRight} = this.Ctx.ctx.measureText(ele.textInfo.text); // 获取文字元素信息（宽高）
    
    res.lineHeight = actualBoundingBoxAscent + actualBoundingBoxDescent + 6;

    res.x = - (actualBoundingBoxLeft + actualBoundingBoxRight) / 2;
    res.y = (actualBoundingBoxAscent + actualBoundingBoxDescent) / 2 - actualBoundingBoxDescent;
    
    // 获取不同图案的 左上角顶点 和 最大宽度
    let computeProp = {vertex: {x:0, y:0}, width: 0};
    if(['rect', 'image'].includes(ele.type)){
      computeProp.vertex = {x:ele.x, y:ele.y};
      computeProp.width = maxWidth;
      return this.textBreak({ele, computeProp, res})   // 目前只有矩形和圆形需要 文字换行
    }else if(ele.type === 'circular'){
      computeProp.vertex = {x:ele.x - ele.radiusX, y:ele.y - ele.radiusY};
      computeProp.width = maxWidth;
      return this.textBreak({ele, computeProp, res})
    }else if(['connectArrowCurveFill', 'connectCurve', 'line'].includes(ele.type)){
      return this.textBreak({ele, computeProp, res})
    }

    res.textArr = [ele.textInfo.text];
    return res
  }

  // 处理文字换行
  textBreak({ele, computeProp, res}){

    let text = ele.textInfo.text.split('/n');

    let arr = [];

    for(let i of text){
      arr.push(i.split(''));
    }

    // 如果是线，需要先单独算出来分割后的最长字符串长度（因为线形不知道文字最大宽度是多少，无法算出文字初始位置，所以要根据手动输入的换行符来计算）
    if(['connectArrowCurveFill', 'connectCurve', 'line'].includes(ele.type)){
      let maxWidth = 0;
      for(let t of arr){
        let tag = 0;
        for(let i of t){
          let {actualBoundingBoxLeft, actualBoundingBoxRight} = this.Ctx.ctx.measureText(i);
          tag += actualBoundingBoxLeft + actualBoundingBoxRight
        }
        if(tag + 20 > maxWidth) maxWidth = tag + 20
      }
      computeProp.width = maxWidth
    }

    let maxWidth = 0;
    let maxText = '';
    // 处理每一行文字（抛开手动换行外，还可能会产生自动换行
    for(let t of arr){
      maxWidth = 0;
      maxText = '';
      for(let i of t){
        if(i === ' ') maxWidth += 2;
        let {actualBoundingBoxLeft, actualBoundingBoxRight} = this.Ctx.ctx.measureText(i); // 获取文字元素信息（宽高）
        if(actualBoundingBoxLeft + actualBoundingBoxRight + maxWidth + 20 > computeProp.width){
          // 总长度超出了单行最大长度限制
          res.x = - computeProp.width/2 + 3;
          res.y = - res.lineHeight * res.textArr.length /2;
          res.textArr.push(maxText)
          maxWidth = actualBoundingBoxLeft + actualBoundingBoxRight;
          maxText = i;
        }else{
          if(arr.length !== 1){
            // 如果存在换行，则重新计算文字起点
            res.x = - computeProp.width/2 + 3;
            res.y = - res.lineHeight * res.textArr.length /2;
          }
          maxText += i;
          maxWidth += actualBoundingBoxLeft + actualBoundingBoxRight
        }
      }
      if(maxText) res.textArr.push(maxText)
    }
    return res
  }

}